;(function () {
  //#------联合类型
  type Result7 = 1 extends 1 | 2 | 3 ? 1 : 2 // 1
  type Result8 = 'lys' extends 'lys' | 'l' | 'ly' ? 1 : 2 // 1
  type Result9 = true extends true | false ? 1 : 2

  //在这一层面上，并不需要联合类型的所有成员均为字面量类型，或者字面量类型来自于同一基础类型这样的前提，只需要这个类型存在于联合类型中。
  type Result10 = string extends string | false | number ? 1 : 2 //1
  //结论：字面量类型 < 包含此字面量类型的联合类型，原始类型 < 包含此原始类型的联合类型。

  //而如果一个联合类型由同一个基础类型的类型字面量组成，那这个时候情况又有点不一样了。既然你的所有类型成员都是字符串字面量类型，那你岂不就是我 string 类型的小弟？如果你的所有类型成员都是对象、数组字面量类型或函数类型，那你岂不就是我 object 类型的小弟？
  type Result11 = 'lin' | 'bu' | 'budu' extends string ? 1 : 2
  type Result12 = {} | (() => void) | [] extends object ? 1 : 2 // 1
  // 结论：同一基础类型的字面量联合类型 < 此基础类型。
  //合并一下结论，去掉比较特殊的情况: 字面量类型 < 包含此字面量类型的联合类型（同一基础类型） < 对应的原始类型

  type Result13 = 'lys' extends 'lys' | '599' ? ('lys' | '599' extends string ? 2 : 1) : 0

  // #-----------装箱类型
  //TypeScript 中的体现： String 类型，以及在原型链顶端傲视群雄的 Object 对象与 Object 类型。
  //很明显，string 类型会是 String 类型的子类型，String 类型会是 Object 类型的子类型，那中间还有吗？还真有，而且你不一定能猜到。我们直接看从 string 到 Object 的类型层级：
  type Result14 = string extends String ? 1 : 2 //1
  type Result15 = String extends {} ? 1 : 2 //1
  type Result16 = {} extends object ? 1 : 2 //1
  type Result17 = object extends Object ? 1 : 2 //1

  //这里看着像是混进来一个很奇怪的东西，{} 不是 object 的字面量类型吗？为什么能在这里比较，并且 String 还是它的子类型？这时请回忆我们在结构化类型系统中一节学习到的概念，假设我们把 String 看作一个普通的对象，上面存在一些方法，如：
  interface FuncFooStruct {
    (name: string): string
  }
  interface String {
    replace: FuncFooStruct
    replaceAll: FuncFooStruct
    startsWith: FuncFooStruct
    endsWith: FuncFooStruct
    includes: FuncFooStruct
  }
  //但实际上 string extends object 并不成立：
  type Tmp = string extends object ? 1 : 2 //2

  //由于结构化类型系统这一特性的存在，我们能得到一些看起来矛盾的结论：
  type Result18 = {} extends object ? 1 : 2
  type Result19 = object extends {} ? 1 : 2

  type Result20 = object extends Object ? 1 : 2
  type Result21 = Object extends object ? 1 : 2

  type Result22 = Object extends {} ? 1 : 2
  type Result23 = {} extends Object ? 1 : 2
  //为什么无论如何判断都成立？难道说明 {} 和 object 类型相等，也和 Object 类型一致？
  type Result24 = Object extends any ? 1 : 2 // 1
  type Result25 = Object extends unknown ? 1 : 2 //1

  type Result26 = any extends Object ? 1 : 2
  type Result27 = unknown extends Object ? 1 : 2

  type Result28 = any extends 'lys' ? 1 : 2
  type Result29 = any extends string ? 1 : 2
  type Result30 = any extends {} ? 1 : 2
  type Result31 = any extends never ? 1 : 2
  //在 TypeScript 内部代码的条件类型处理中，如果接受判断的是 any，那么会直接返回条件类型结果组成的联合类型。

  // 因此 any extends string 并不能简单地认为等价于以下条件类型：
  type Result32 = 'lys' | {} extends string ? 1 : 2 //2

  //any来者不拒，而 unknown 则只允许赋值给 unknown 类型和 any 类型，这也是由于“系统设定”的原因，即 any 可以表达为任何类型。你需要我赋值给这个变量？那我现在就是这个变量的子类型了，我是不是很乖巧？

  //另外，any 类型和 unknown 类型的比较也是互相成立的：
  type Result33 = any extends unknown ? 1 : 2 // 1
  type Result34 = unknown extends any ? 1 : 2 // 1

})()
